using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Text;
using System.Windows.Forms;
using System.Management;
using Microsoft.BizTalk;
using Microsoft.BizTalk.Message.Interop;
using Microsoft.BizTalk.Operations;
using System.Reflection;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using System.IO;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Collections;
using System.Xml;
using Microsoft.BizTalk.Agent.Interop;
using Microsoft.BizTalk.Component.Interop;
using BTSDecompress.ClassLibrary;
using BTSDecompress.Controls;
using log4net;
namespace BTSDecompress
{
    /// <summary>
    /// Thiago Almeida - http://connectedthoughts.wordpress.com
    /// Lex Hegt - http://biztalkia.blogspot.com
    /// Application to retrieve messages from BizTalk MessageBox and Tracking database
    /// http://connectedthoughts.wordpress.com/2008/04/02/3-ways-of-programatically-extracting-a-message-body-from-the-biztalk-tracking-database/
    /// </summary>
    public partial class GetTrackedMessage : Form
    {
        #region Variables
        Boolean _RecordProtection = true;
        readonly ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        #endregion
        #region Constructors
        public GetTrackedMessage()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            InitializeComponent();

            // Give some controls a default value
            maxNrOfRecords.SelectedItem = "10";

            // Set the file name
            //queryControl.CurrentFile = Directory.GetCurrentDirectory() + "\\New Query.sql";
            //queryControl.CurrentFileNameOnly = "New Query.sql";

            //this.Text = queryControl.CurrentFileNameOnly + " - BTSDecompress";

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        public GetTrackedMessage(Boolean RecordProtection) : this()
        {
            // To prevent too much load on the BizTalk database, you can turn 
            // Recordprotection on/off from the commandline with the parameter -p 
            _RecordProtection = RecordProtection;
        }
        #endregion
        #region Methods
        private void AddTabPage()
        {
            TabPage tabPage = new TabPage("New Tab");
            Padding margin = tabPage.Margin;
            margin.All = 0;
            Padding padding = tabPage.Padding;
            padding.All = 0;

            querytabControl.TabPages.Add(tabPage);

            BTSDecompress.Controls.QueryControl q = new BTSDecompress.Controls.QueryControl();
            q.Name = "q1";
            //tabPage.Text = false ? string.Format("{0} (*) - BTSDecompress", queryControl.CurrentFileNameOnly) : string.Format("{0} - BTSDecompress", queryControl.CurrentFileNameOnly);

            try
            {
                tabPage.Controls.Add(q);
            }
            catch (ArgumentException e)
            {
                MessageBox.Show(e.Message);
                throw;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                throw;
            }
        }
        /// <summary>
        /// Initializes the controls to certain default values
        /// </summary>
        private void ClearScreen()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            queryControl.ClearScreen();

            databaseServerTextBox.Text = "";
            databasesComboBox.Text = "";
            namespacesListView.Items.Clear();
            hideInnerOuterXmlCheckBox.Checked = false;
            hideContextPropertyNamesCheckBox.Checked = false;
            showCommentsCheckBox.Checked = false;
            saveSettingsCheckBox.Checked = true;
            showColumnNamesCheckBox.Checked = false;
            useFieldSeperatorCheckBox.Checked = true;
            blankLineCheckBox.Checked = false;
            wordWrapMenuItem.Checked = true;
            maxNrOfRecords.Text = "10";
            SetDirty(false);

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private void CloseTabPage()
        {

            if (querytabControl.TabPages.Count == 1)
            {
                return;
            }

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            TabPage tabPage = querytabControl.SelectedTab;

            // Warn the user that the current will be cleaned
            if (queryControl.Query.Text.Length > 0 && queryControl.IsDirty == true)
            {
                if (MessageBox.Show("The current query is not saved!\nAre you sure you want to continue?", "BTSDecompress", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == System.Windows.Forms.DialogResult.No)
                {
                    return;
                }
            }

            // Close the tab
            querytabControl.TabPages.Remove(tabPage);

        }
        /// <summary>
        /// This method becomes called after the user hit the 'Execute' button. 
        /// </summary>
        private void Execute()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            // Check if a database server was entered in the textbox
            if (databasesComboBox.Text.Length == 0)
            {
                MessageBox.Show("You must enter a database server.", "BTSDecompress");
                return;
            }

            // Check if a database was selected from the dropdown
            if (databasesComboBox.SelectedItem == null || databasesComboBox.SelectedItem.ToString() == "")
            {
                MessageBox.Show("You must select a database from the dropdownbox.", "BTSDecompress");
                return;
            }

            TabPage tabPage = querytabControl.SelectedTab;
            BTSDecompress.Controls.QueryControl queryControl1 = (BTSDecompress.Controls.QueryControl)tabPage.Controls[0];

            // Clear the output textbox and gridview
            queryControl1.ClearOutputControls();

            Cursor = Cursors.WaitCursor;

            try
            {
                // Insert TOP xx-protection
                if (_RecordProtection)
                {
                    queryControl1.Query.Text = Utils.PreProcessQuery(queryControl1.Query.Text, Convert.ToInt16(maxNrOfRecords.SelectedItem));
                }

                // Load the query
                LoadQuery();

                // Execute the query
                DataTable dataTable;
                queryControl1.OutputTextBox.Text = Utils.ExecuteQuery(queryControl1.sqlQuery, out dataTable);
                queryControl1.OutputGridViewDataSource = dataTable;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

            Cursor = Cursors.Default;

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// Closes the application
        /// </summary>
        private Boolean Exit()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            Hashtable UnsavedQueries = new Hashtable();

            // Check for any unsaved queries
            foreach (TabPage tabPage in querytabControl.TabPages)
            {
                BTSDecompress.Controls.QueryControl queryControl = (BTSDecompress.Controls.QueryControl)tabPage.Controls[0];

                // If the query has not been saved, warn the user
                if (queryControl.IsDirty)
                {
                    UnsavedQueries.Add(queryControl.CurrentFile, queryControl);
                }
            }

            // If there are any unsaved queries, ask if they should be saved
            if (UnsavedQueries.Count > 0)
            {
                fdlgUnsavedQueries UnsavedQueriesForm = new fdlgUnsavedQueries(UnsavedQueries);

                DialogResult dialogResult = UnsavedQueriesForm.ShowDialog();

                //DialogResult dialogResult = MessageBox.Show(String.Format("One or more queries have not been saved. Are you sure you want to close the application?"), "BTSDecompress", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                switch(dialogResult)
                {
                    case DialogResult.Yes:
                    {

                        UnsavedQueries = UnsavedQueriesForm.StoreUnsavedQueries;

                        foreach (DictionaryEntry entry in UnsavedQueries)
                        {
                            QueryControl queryControl = (QueryControl)entry.Value;
                            if (queryControl.sqlQuery.SaveSettings == true)
                            {
                                File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.FullText);
                            }
                            else
                            {
                                File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.CommandText);
                            }
                        }

                        log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
                        //break;
                        return true;
                    }
                    case DialogResult.No:
                    {
                        log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
                        //break;
                        return true;
                    }
                    case DialogResult.Cancel:
                    {
                        log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
                        //break;
                        return false;
                    }
                }
            }

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
            return true;
        }
        private void FillNamespaces()
        {

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();

            namespacesListView.Items.Clear();

            foreach (DictionaryEntry entry in queryControl.sqlQuery.Namespaces)
            {
                ListViewItem item = new ListViewItem();
                item.Text = string.Format("{0}: {1}", entry.Key.ToString(), entry.Value.ToString());
                namespacesListView.Items.Add(item);
            }
        }
        /// <summary>
        /// Fills the controls based on the values from the query
        /// </summary>
        private void FillScreen()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();

            databaseServerTextBox.Text = queryControl.sqlQuery.DatabaseServer;
            if (databaseServerTextBox.Text != "")
            {
                LoadDatabases(queryControl.sqlQuery.DatabaseServer);
                databasesComboBox.SelectedItem = queryControl.sqlQuery.Database;
            }
            
            hideInnerOuterXmlCheckBox.Checked = queryControl.sqlQuery.HideOuterXMLTag;
            hideContextPropertyNamesCheckBox.Checked = queryControl.sqlQuery.HideContextPropertyNames;
            showCommentsCheckBox.Checked = queryControl.sqlQuery.ShowComments;
            showColumnNamesCheckBox.Checked = queryControl.sqlQuery.ShowColumnNames;
            useFieldSeperatorCheckBox.Checked = queryControl.sqlQuery.UseFieldSeparator;
            blankLineCheckBox.Checked = queryControl.sqlQuery.BlankLineBetweenRecords;
            wordWrapMenuItem.Checked = queryControl.sqlQuery.WordWrap;
            maxNrOfRecords.SelectedItem = (int)queryControl.sqlQuery.ShowMaxNrOfRecords;

            FillNamespaces();

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private BTSDecompress.Controls.QueryControl GetCurrentQueryControl()
        {
            TabPage tabPage = querytabControl.SelectedTab;
            return (BTSDecompress.Controls.QueryControl)tabPage.Controls[0];
        }
        private TabPage GetExistingTabPage(string File)
        {
            foreach(TabPage tabPage in querytabControl.TabPages)
            {
                BTSDecompress.Controls.QueryControl queryControl = (BTSDecompress.Controls.QueryControl)tabPage.Controls[0];

                if (queryControl.CurrentFile == File)
                {
                    return tabPage;
                }
            }
            return null;
        }
        private string GetVersion()
        {
            Version ver;
            try
            {
                Assembly assem = Assembly.GetEntryAssembly();
                AssemblyName assemName = assem.GetName();
                ver = assemName.Version;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return "v" + ver.ToString();
        }
        /// <summary>
        /// Initializes some local variables and clear the Result TextBox
        /// </summary>
        /// <summary>
        /// Loads the databases
        /// </summary>
        private void LoadDatabases(string dataBaseServer)
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            // Initialize the connection string
            String connString = String.Format("Data Source={0}; Integrated Security=True;", dataBaseServer);

            // Clear the list
            databasesComboBox.Items.Clear();
            try
            {
                // Initialize the connection
                using (SqlConnection cn = new SqlConnection(connString))
                {
                    // Retrieve the databases
                    cn.Open();
                    DataTable tblDatabases = cn.GetSchema("Databases");
                    cn.Close();

                    // Fill the combobox with the databases
                    foreach (DataRow row in tblDatabases.Rows)
                    {
                        string db = row["database_name"].ToString();
                        databasesComboBox.Items.Add(db);
                    }
                }
                //databasesComboBox.SelectedItem = "BizTalkMsgBoxDb";

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "BTSDecompress", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// Loads a file which contains a query
        /// </summary>
        /// <param name="file">Name and location of the file</param>
        /// <param name="showComments">Whether or not show the comments which contain thee settings</param>
        /// <returns></returns>
        private string LoadFile(string file, bool showComments)
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = null;

            string query = "";
            bool bHeaderRead = false;
            string[] lines = File.ReadAllLines(file);

            queryControl = GetCurrentQueryControl();

            for (int i = 0; i < lines.Length; i++)
            {
                // Show/hide comments
                if (lines[i].StartsWith("--") && (showComments==true || (showComments == false && bHeaderRead==true)))
                {
                    query += string.Format("{0}\r\n", lines[i]);
                }

                // Show query)
                if (!lines[i].StartsWith("--"))
                {
                    bHeaderRead = true;
                    query += string.Format("{0}\r\n", lines[i]);
                    //SqlQuery.CommandText += query;
                    queryControl.sqlQuery.CommandText += query;
                }

                // Get first 31 characters of the line 
                // (this is a little bit more than the length of the longest option)
                string line = lines[i].Substring(0, lines[i].Length > 31 ? 31 : lines[i].Length);
                
                switch (line.ToLower().TrimEnd())
                {
                    case "-- database server":
                        {
                            databaseServerTextBox.Text = lines[i].Substring(33);
                            queryControl.sqlQuery.DatabaseServer = lines[i].Substring(33);
                            break;
                        }
                    case "-- database":
                        {
                            LoadDatabases(databaseServerTextBox.Text);
                            databasesComboBox.SelectedItem = lines[i].Substring(33);
                            databasesComboBox.Text = lines[i].Substring(33);
                            queryControl.sqlQuery.Database = lines[i].Substring(33);
                            break;
                        }
                    case "-- namespace":
                        {
                            try
                            {
                                string[] ns = lines[i].Substring(33).Split(' ');
                                queryControl.sqlQuery.Namespaces.Add(ns[0].ToString(), ns[1].ToString());

                                ListViewItem item = new ListViewItem();
                                item.Text = string.Format("{0}: {1}", ns[0].ToString(), ns[1].ToString());
                                namespacesListView.Items.Add(item);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(string.Format("Error loading Namespace.\r\n{0}", ex.Message),"BTSDecompress"); 
                            }
                            break;
                        }
                    case "-- hide outer xml tag":
                        {
                            hideInnerOuterXmlCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.HideOuterXMLTag = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- hide context property names":
                        {
                            hideContextPropertyNamesCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.HideContextPropertyNames = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- show comments":
                        {
                            showCommentsCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.ShowComments = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- save settings":
                        {
                            saveSettingsCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.SaveSettings = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- show column names":
                        {
                            showColumnNamesCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.ShowColumnNames = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- use field seperator":
                        {
                            useFieldSeperatorCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.UseFieldSeparator = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- blank line between records":
                        {
                            blankLineCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.BlankLineBetweenRecords = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- word wrap":
                        {
                            wordWrapMenuItem.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.WordWrap = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    default:
                        { break; }
                }
            }
            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
            return query;
        }
        private string LoadFile(string file, Hashtable parameters, bool showComments)
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = null;

            string query = "";
            bool bHeaderRead = false;
            string[] lines = File.ReadAllLines(file);

            queryControl = GetCurrentQueryControl();

            databaseServerTextBox.Text = parameters["databaseserver"].ToString();
            queryControl.sqlQuery.DatabaseServer = parameters["databaseserver"].ToString();

            LoadDatabases(databaseServerTextBox.Text);
            databasesComboBox.SelectedItem = parameters["database"].ToString();
            databasesComboBox.Text = parameters["database"].ToString();
            queryControl.sqlQuery.Database = parameters["database"].ToString();

            for (int i = 0; i < lines.Length; i++)
            {
                // Show/hide comments
                if (lines[i].StartsWith("--") && (showComments == true || (showComments == false && bHeaderRead == true)))
                {
                    query += string.Format("{0}\r\n", lines[i]);

                }

                // Show query)
                if (!lines[i].StartsWith("--"))
                {
                    bHeaderRead = true;
                    query += string.Format("{0}\r\n", lines[i]);
                    //SqlQuery.CommandText += query;
                    queryControl.sqlQuery.CommandText += query;
                }

                // Get first 31 characters of the line 
                // (this is a little bit more than the length of the longest option)
                string line = lines[i].Substring(0, lines[i].Length > 31 ? 31 : lines[i].Length);

                switch (line.ToLower().TrimEnd())
                {
                    case "-- namespace":
                        {
                            try
                            {
                                string[] ns = lines[i].Substring(33).Split(' ');
                                queryControl.sqlQuery.Namespaces.Add(ns[0].ToString(), ns[1].ToString());

                                ListViewItem item = new ListViewItem();
                                item.Text = string.Format("{0}: {1}", ns[0].ToString(), ns[1].ToString());
                                namespacesListView.Items.Add(item);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(string.Format("Error loading Namespace.\r\n{0}", ex.Message), "BTSDecompress");
                            }
                            break;
                        }
                    case "-- hide outer xml tag":
                        {
                            hideInnerOuterXmlCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.HideOuterXMLTag = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- hide context property names":
                        {
                            hideContextPropertyNamesCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.HideContextPropertyNames = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- show comments":
                        {
                            showCommentsCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.ShowComments = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- save settings":
                        {
                            saveSettingsCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.SaveSettings = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- show column names":
                        {
                            showColumnNamesCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.ShowColumnNames = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- use field seperator":
                        {
                            useFieldSeperatorCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.UseFieldSeparator = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- blank line between records":
                        {
                            blankLineCheckBox.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.BlankLineBetweenRecords = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    case "-- word wrap":
                        {
                            wordWrapMenuItem.Checked = Convert.ToBoolean(lines[i].Substring(33));
                            queryControl.sqlQuery.WordWrap = Convert.ToBoolean(lines[i].Substring(33));
                            break;
                        }
                    default:
                        { break; }
                }
            }

            foreach (System.Collections.DictionaryEntry entry in parameters)
            {
                if (Convert.ToString(entry.Key) != "databaseserver" && Convert.ToString(entry.Key) != "database")
                {
                    string key = "{" + Convert.ToString(entry.Key).ToLower() + "}";
                    string value = Convert.ToString(entry.Value);

                    StringBuilder sb = new StringBuilder(query);
                    sb.Replace(key, value);
                    query = sb.ToString();
                }
            }

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
            return query;
        }
        /// <summary>
        /// Loads the query, based on the values of the controls, before the query is executed
        /// </summary>
        private void LoadQuery()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            string commandText = queryControl.Query.Text;

            if (queryControl.Query.SelectedText.Length > 0)
            {
                commandText = queryControl.Query.SelectedText;
            }
            
            queryControl.sqlQuery.Clear();
            queryControl.sqlQuery.DatabaseServer = databaseServerTextBox.Text;
            queryControl.sqlQuery.Database = databasesComboBox.SelectedItem == null ? "" : databasesComboBox.SelectedItem.ToString();
            queryControl.sqlQuery.CommandText = commandText;

            for (int i = 0; i < namespacesListView.Items.Count; i++)
            {
                ListViewItem item = namespacesListView.Items[i];

                string[] s = item.Text.Split(' ');
                queryControl.sqlQuery.Namespaces.Add(s[0].Substring(0, s[0].Length - 1), s[1]);
            }

            queryControl.sqlQuery.BlankLineBetweenRecords = blankLineCheckBox.Checked;
            queryControl.sqlQuery.HideOuterXMLTag = hideInnerOuterXmlCheckBox.Checked;
            queryControl.sqlQuery.HideContextPropertyNames = hideContextPropertyNamesCheckBox.Checked;
            queryControl.sqlQuery.SaveSettings = saveSettingsCheckBox.Checked;
            queryControl.sqlQuery.ShowComments = showCommentsCheckBox.Checked;
            queryControl.sqlQuery.ShowMaxNrOfRecords = Convert.ToInt16(maxNrOfRecords.SelectedItem.ToString());
            queryControl.sqlQuery.ShowColumnNames = showColumnNamesCheckBox.Checked;
            queryControl.sqlQuery.UseFieldSeparator = useFieldSeperatorCheckBox.Checked;
            queryControl.sqlQuery.WordWrap = wordWrapMenuItem.Checked;

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// Start a new query
        /// </summary>
        private void NewQuery()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
            
            // Check if the selected file is already opened
            TabPage tabPage = new TabPage("New Query.sql");
            tabPage.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top);

            BTSDecompress.Controls.QueryControl queryControl = new BTSDecompress.Controls.QueryControl();
            queryControl.Location = new Point(-1, 0);
            queryControl.Size = new System.Drawing.Size(tabPage.Size.Width, tabPage.Size.Height);
            queryControl.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top);
            
            tabPage.Controls.Add(queryControl);
            querytabControl.TabPages.Add(tabPage);
            querytabControl.SelectedTab = tabPage;

            queryControl.sqlQuery.Clear();
            ClearScreen();

            queryControl.CurrentFile = Directory.GetCurrentDirectory() + "\\New Query.sql";
            queryControl.CurrentFileNameOnly = "New Query.sql";
            //this.Text = queryControl.CurrentFileNameOnly;

            //queryControl.Query.Text = LoadFile(queryControl.CurrentFile, showCommentsCheckBox.Checked);
            FillScreen();

            queryControl.SetDirty(false);

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private void OpenFile(string fileName)
        {
            tsStatusMessage.Text = "Create new tab page";
            tsStatusMessage.Invalidate();

            // Check if the selected file is already opened
            TabPage tabPage = GetExistingTabPage(fileName);

            if (tabPage != null)
            {
                querytabControl.SelectedTab = tabPage;
                return;
            }

            tabPage = new TabPage("New Query.sql");
            tabPage.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top);

            BTSDecompress.Controls.QueryControl queryControl = new BTSDecompress.Controls.QueryControl();
            queryControl.Location = new Point(-1, 0);
            queryControl.Size = new System.Drawing.Size(tabPage.Size.Width, tabPage.Size.Height);
            queryControl.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top);

            tabPage.Controls.Add(queryControl);
            querytabControl.TabPages.Add(tabPage);
            querytabControl.SelectedTab = tabPage;

            queryControl.sqlQuery.Clear();
            ClearScreen();

            queryControl.CurrentFile = fileName;
            queryControl.CurrentFileNameOnly = queryControl.CurrentFile.Substring(queryControl.CurrentFile.LastIndexOf('\\') + 1);
            //this.Text = queryControl.CurrentFileNameOnly;

            tsStatusMessage.Text = "Opening query";
            tsStatusMessage.Invalidate();

            queryControl.Query.Text = LoadFile(queryControl.CurrentFile, showCommentsCheckBox.Checked);
            FillScreen();

            queryControl.SetDirty(false);
            tsStatusMessage.Text = "";
            tsStatusMessage.Invalidate();
        }
        private void OpenPredefinedQuery(string fileName, Hashtable parameters)
        {
            string newQuery = "New Query.sql";
            tsStatusMessage.Text = "Create new tab page";
            tsStatusMessage.Invalidate();

            // Check if the selected file is already opened
            //TabPage tabPage = GetExistingTabPage(fileName);

            TabPage tabPage = new TabPage(newQuery);
            tabPage.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top);

            BTSDecompress.Controls.QueryControl queryControl = new BTSDecompress.Controls.QueryControl();
            queryControl.Location = new Point(-1, 0);
            queryControl.Size = new System.Drawing.Size(tabPage.Size.Width, tabPage.Size.Height);
            queryControl.Anchor = (AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top);

            tabPage.Controls.Add(queryControl);
            querytabControl.TabPages.Add(tabPage);
            querytabControl.SelectedTab = tabPage;

            queryControl.sqlQuery.Clear();
            ClearScreen();

            queryControl.CurrentFile = newQuery;
            queryControl.CurrentFileNameOnly = newQuery;
            //queryControl.CurrentFile = fileName;
            //queryControl.CurrentFileNameOnly = queryControl.CurrentFile.Substring(queryControl.CurrentFile.LastIndexOf('\\') + 1);
            //this.Text = queryControl.CurrentFileNameOnly;

            tsStatusMessage.Text = "Opening query";
            tsStatusMessage.Invalidate();

            queryControl.Query.Text = LoadFile(fileName, parameters, showCommentsCheckBox.Checked);
            FillScreen();

            queryControl.SetDirty(false);
            tsStatusMessage.Text = "";
            tsStatusMessage.Invalidate();
        }
        /// <summary>
        /// Open a file which contains a SQL query
        /// </summary>
        private void OpenFileDialog()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            // Open a FileOpen Dialog
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.InitialDirectory = Directory.GetCurrentDirectory();
            openFileDialog.Filter = "SQL files (*.sql)|*.sql|All Files (*.*)|*.*";
            DialogResult dialogResult = openFileDialog.ShowDialog();

            // If the user clicked the Cancel button, leave this method
            if (dialogResult != System.Windows.Forms.DialogResult.OK)
            {
                return;
            }

            Cursor = Cursors.WaitCursor;
            foreach (string fileName in openFileDialog.FileNames)
            {
                OpenFile(fileName);
            }
            Cursor = Cursors.Default;

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private void OpenPredefinedQueryDialog()
        {
            PredefinedQueryDialog predefinedQueryDialog = new PredefinedQueryDialog();
            DialogResult dialogResult = predefinedQueryDialog.ShowDialog();

            if (dialogResult != DialogResult.OK)
            {
                return;
            }

            string fileName = predefinedQueryDialog.FileName;
            Hashtable hashTable = predefinedQueryDialog.Parameters;

            OpenPredefinedQuery(fileName, hashTable);
        }
        /// <summary>
        /// Catches pressing of hotkeys
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keyData"></param>
        /// <returns></returns>
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            //log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            if (keyData == Keys.F5)
                Execute();

            if (keyData == (Keys.F4 | Keys.Control))
                CloseTabPage();

            //log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
            return base.ProcessCmdKey(ref msg, keyData);
        }
        private void Redo()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            queryControl.Redo();

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private void SaveAllFiles()
        {
            foreach (TabPage tabPage in querytabControl.TabPages)
            {
                BTSDecompress.Controls.QueryControl queryControl = (BTSDecompress.Controls.QueryControl)tabPage.Controls[0];
                if (queryControl.IsDirty)
                {
                    if (queryControl.sqlQuery.SaveSettings == true)
                    {
                        File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.FullText);
                    }
                    else
                    {
                        File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.CommandText);
                    }

                    SetDirty(queryControl, false);
                }
            }
        }
        /// <summary>
        /// Saves an existing query as a new file
        /// </summary>
        private void SaveAsFile()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            
            //if (_currentFileNameOnly == "New Query.sql" || queryControl.CurrentFileNameOnly == "New Query.sql")
            //if (queryControl.CurrentFileNameOnly == "New Query.sql")
            if (queryControl.CurrentFileNameOnly == "")
            {
                SaveFile();
            }
            else
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.InitialDirectory = Directory.GetCurrentDirectory();
                saveFileDialog.FileName = queryControl.CurrentFileNameOnly;
                saveFileDialog.Filter = "SQL files (*.sql)|*.sql|All Files (*.*)|*.*";
                DialogResult dialogResult = saveFileDialog.ShowDialog();

                if (dialogResult != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }

                //_currentFile = saveFileDialog.FileName;
                //_currentFileNameOnly = _currentFile.Substring(_currentFile.LastIndexOf('\\') + 1);

                queryControl.CurrentFile = saveFileDialog.FileName;
                queryControl.CurrentFileNameOnly = queryControl.CurrentFile.Substring(queryControl.CurrentFile.LastIndexOf('\\') + 1);
            }

            LoadQuery();

            if (queryControl.sqlQuery.SaveSettings == true)
            {
                File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.FullText);
            }
            else
            {
                File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.CommandText);
            }

            SetDirty(false);

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// Saves a query as a file
        /// </summary>
        private void SaveFile()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();

            //if (queryControl.CurrentFileNameOnly == "New Query.sql")
            if (queryControl.CurrentFileNameOnly == "")
                {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.InitialDirectory = Directory.GetCurrentDirectory();
                //saveFileDialog.FileName = queryControl.CurrentFileNameOnly;
                saveFileDialog.FileName = "New Query.sql";
                saveFileDialog.Filter = "SQL files (*.sql)|*.sql|All Files (*.*)|*.*";
                DialogResult dialogResult = saveFileDialog.ShowDialog();

                if (dialogResult != System.Windows.Forms.DialogResult.OK)
                {
                    return;
                }
                
                queryControl.CurrentFile = saveFileDialog.FileName;
                queryControl.CurrentFileNameOnly = queryControl.CurrentFile.Substring(queryControl.CurrentFile.LastIndexOf('\\') + 1);
            }

            LoadQuery();

            if (queryControl.sqlQuery.SaveSettings == true)
            {
                File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.FullText);
            }
            else
            {
                File.WriteAllText(queryControl.CurrentFile, queryControl.sqlQuery.CommandText);
            }

            SetDirty(false);

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// In case a value has changed, the dirty bit is set and is reflected in the title of the screen
        /// </summary>
        /// <param name="dirty"></param>
        private void SetDirty(Boolean dirty)
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            queryControl.SetDirty(dirty);
            //this.Text = dirty ? string.Format("{0} (*)", queryControl.CurrentFileNameOnly) : string.Format("{0}", queryControl.CurrentFileNameOnly);
            //this.Text = "BTSDecompress";

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private void SetDirty(BTSDecompress.Controls.QueryControl queryControl, Boolean dirty)
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            //BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            queryControl.SetDirty(dirty);

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// Shows the About Box
        /// </summary>
        private void ShowAboutBox()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            AboutBox aboutbox = new AboutBox();
            aboutbox.ShowDialog();

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        /// <summary>
        /// Shows and handles the Namespaces dialog
        /// </summary>
        private void ShowNamespacesDialog()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            NameSpacesDialog nameSpacesDialog = new NameSpacesDialog(namespacesListView.Items);
            DialogResult dr = nameSpacesDialog.ShowDialog();

            if (dr == DialogResult.OK)
            {
                BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();

                queryControl.sqlQuery.Namespaces = nameSpacesDialog.Namespaces;

                namespacesListView.Items.Clear();

                foreach (DictionaryEntry entry in queryControl.sqlQuery.Namespaces)
                {
                    ListViewItem item = new ListViewItem();
                    item.Text = string.Format("{0}: {1}", entry.Key.ToString(), entry.Value.ToString());
                    namespacesListView.Items.Add(item);
                }
                SetDirty(true);
            }

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        private void Undo()
        {
            log.Debug(string.Format("BEGIN - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));

            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            queryControl.Undo();

            log.Debug(string.Format("END - {0}", System.Reflection.MethodInfo.GetCurrentMethod().ToString()));
        }
        #endregion
        #region Events
        private void AboutMenuItem_Click(object sender, EventArgs e)
        {
            ShowAboutBox();
        }
        private void addTabPageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddTabPage();
        }
        private void CloseMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        private void closeTabPageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CloseTabPage();
        }
        private void DatabasesComboBox_Enter(object sender, EventArgs e)
        {
            LoadDatabases(databaseServerTextBox.Text);
        }
        private void DatabasesComboBox_SelectedValueChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void DatabasesComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void DataBaseServerTextBox_TextChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void ExecuteButton_Click(object sender, EventArgs e)
        {
            Execute();
        }
        private void FontMenuItem_Click(object sender, EventArgs e)
        {
            QueryControl queryControl = GetCurrentQueryControl();
            FontDialog fontDialog = new FontDialog();
            fontDialog.Font = queryControl.Query.Font;

            DialogResult dialogResult = fontDialog.ShowDialog();

            if (dialogResult == System.Windows.Forms.DialogResult.OK)
            {
                queryControl.Query.Font = fontDialog.Font;
                queryControl.OutputTextBox.Font = fontDialog.Font;
            }
        }
        private void GetTrackedMessage_Load(object sender, EventArgs e)
        {
            SetDirty(false);
            tsVersion.Text = GetVersion();
        }
        private void GetTrackedMessage_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = !Exit();
        }
        private void HideContextPropertyNamesCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void HideInnerOuterXmlCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void MaxNrOfRecords_SelectedIndexChanged(object sender, EventArgs e)
        {
            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();

            if (_RecordProtection && queryControl.Query.Text.Length > 0)
            {
                queryControl.Query.Text = Utils.PreProcessQuery(queryControl.Query.Text, Convert.ToInt16(maxNrOfRecords.SelectedItem));
            }
            SetDirty(true);
        }
        private void NameSpaces_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            ShowNamespacesDialog();
        }
        private void NewMenuItem_Click(object sender, EventArgs e)
        {
            NewQuery();
        }
        private void newQueryToolStripButton_Click(object sender, EventArgs e)
        {
            NewQuery();
        }
        private void OpenMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog();
        }
        private void openPredefinedQueryMenuItem_Click(object sender, EventArgs e)
        {
            OpenPredefinedQueryDialog();
        }
        private void openQueryToolStripButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog();
        }
        private void ParseXmlButton_Click(object sender, EventArgs e)
        {
            fdlgParseXML f = new fdlgParseXML();
            f.ShowDialog();
        }
        private void querytabControl_Deselected(object sender, TabControlEventArgs e)
        {
            // Get the originating tabpage
            TabPage tabPage = e.TabPage;
            if (tabPage == null)
            { return; }

            // Get a reference to the QueryControl
            BTSDecompress.Controls.QueryControl queryControl = (BTSDecompress.Controls.QueryControl)tabPage.Controls[0];

            // If changes has been made to the parameters of the query, store those changes in the QueryControl
            if (queryControl.IsDirty == true)
            {
                queryControl.sqlQuery.DatabaseServer = databaseServerTextBox.Text;
                queryControl.sqlQuery.Database = (databasesComboBox.SelectedItem == null) ? "" : databasesComboBox.SelectedItem.ToString();
                queryControl.sqlQuery.HideOuterXMLTag = hideInnerOuterXmlCheckBox.Checked;
                queryControl.sqlQuery.HideContextPropertyNames = hideContextPropertyNamesCheckBox.Checked;
                queryControl.sqlQuery.ShowComments = showCommentsCheckBox.Checked;
                queryControl.sqlQuery.SaveSettings = saveSettingsCheckBox.Checked;
                queryControl.sqlQuery.ShowColumnNames = showColumnNamesCheckBox.Checked;
                queryControl.sqlQuery.UseFieldSeparator = useFieldSeperatorCheckBox.Checked;
                queryControl.sqlQuery.BlankLineBetweenRecords = blankLineCheckBox.Checked;
                queryControl.sqlQuery.ShowMaxNrOfRecords = Convert.ToInt16(maxNrOfRecords.SelectedItem.ToString());

                // Process the Namespaces 
                queryControl.sqlQuery.Namespaces.Clear();

                foreach (ListViewItem item in namespacesListView.Items)
                {
                    string[] s = item.Text.Split(' ');
                    queryControl.sqlQuery.Namespaces.Add(s[0].Substring(0, s[0].Length - 1), s[1]);

                }
            }
        }
        private void querytabControl_SelectedIndexChanged(object sender, EventArgs e)
        {
            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            Boolean isDirty = queryControl.IsDirty;

            FillScreen();

            queryControl.SetDirty(isDirty);
        }
        private void redoToolStripButton_Click(object sender, EventArgs e)
        {
            Redo();
        }
        private void saveAllToolStripButton_Click(object sender, EventArgs e)
        {
            SaveAllFiles();
        }
        private void saveAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveAllFiles();
        }
        private void SaveAsMenuItem_Click(object sender, EventArgs e)
        {
            SaveAsFile();
        }
        private void SaveMenuItem_Click(object sender, EventArgs e)
        {
            SaveFile();
        }
        private void saveQueryToolStripButton_Click(object sender, EventArgs e)
        {
            SaveFile();
        }
        private void SaveSettingsCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void ShowColumnNamesCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void ShowCommentsCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void undoToolStripButton_Click(object sender, EventArgs e)
        {
            Undo();
        }
        private void UseFieldSeperatorCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            SetDirty(true);
        }
        private void WordWrapMenuItem_Click(object sender, EventArgs e)
        {
            // Get a reference to the QueryControl
            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();
            
            queryControl.OutputTextBox.WordWrap = wordWrapMenuItem.Checked;
            SetDirty(true);
        }
        #endregion

        private void findMenuItem_Click(object sender, EventArgs e)
        {
            BTSDecompress.Controls.QueryControl queryControl = GetCurrentQueryControl();

        }

    }
}